package com.songcha.library_base.handler


import com.songcha.library_base.R
import com.songcha.library_base.interfaces.IApiResult
import com.songcha.library_base.mvvm.exception.CodeException
import com.songcha.library_base.mvvm.exception.LoginTokenInvalidException
import com.songcha.library_base.mvvm.exception.NoDataException
import com.songcha.library_base.mvvm.exception.NoNetworkException
import com.songcha.library_common.BuildConfig
import com.songcha.library_common.LibraryCommon
import com.songcha.library_common.util.ToastUtil
import com.songcha.library_network.api.ApiCode
import com.songcha.library_network.bean.BaseBean
import com.songcha.library_network.util.NetworkUtil
import io.reactivex.Observable
import io.reactivex.Observer
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import okhttp3.RequestBody.Companion.toRequestBody
import retrofit2.HttpException
import java.net.ConnectException
import java.net.SocketTimeoutException
import java.net.UnknownHostException

class ApiObservableHandler {
    companion object{
        //TODO error handle
        @JvmStatic
        private fun onHandleError(e:Throwable,isShowErrorToast: Boolean){
            if(e is NoNetworkException){
                if(isShowErrorToast)
                    ToastUtil.show( LibraryCommon.getContext().resources.getString(R.string.network_no_network))
            } else if(e is ConnectException || e is UnknownHostException){
                if(!NetworkUtil.isNetworkAvailable(LibraryCommon.getContext())){
                    if(isShowErrorToast)
                        ToastUtil.show( LibraryCommon.getContext().resources.getString(R.string.network_no_network))
                    return
                }
                if(isShowErrorToast)
                    ToastUtil.show( LibraryCommon.getContext().resources.getString(R.string.network_connect_error))
            } else if(e is SocketTimeoutException){
                if(!NetworkUtil.isNetworkAvailable(LibraryCommon.getContext())){
                    if(isShowErrorToast)
                        ToastUtil.show( LibraryCommon.getContext().resources.getString(R.string.network_no_network))
                    return
                }
                if(isShowErrorToast)
                    ToastUtil.show( LibraryCommon.getContext().resources.getString(R.string.network_connect_timeout))
            }else if(e is LoginTokenInvalidException){
                /*ARouter.getInstance().build("/business/ClearLoginTokenProviderImpl").navigation()?.let {
                    it as IClearLoginTokenProvider
                    it.clearLoginToken()
                }*/
            } else if(e is NoDataException){

            }else if(e is CodeException){
                if(isShowErrorToast && e.msg.isNotEmpty())
                    ToastUtil.show(e.msg)
            }else if(e is HttpException){
                if(isShowErrorToast && e.message != null)
                    ToastUtil.show(e.message!!)
            } else {
                if(BuildConfig.DEBUG && isShowErrorToast)
                    ToastUtil.show(e.message)
            }
        }

        @JvmStatic
        fun <T:BaseBean> handle(obs:Observable<T>,result:IApiResult<T>, isShowErrorToast:Boolean=true){
            obs.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(object : Observer<T> {
                    override fun onSubscribe(d: Disposable) {

                    }

                    override fun onError(e: Throwable) {
                        result.onError(e)
                        onHandleError(e,isShowErrorToast)
                    }

                    override fun onComplete() {

                    }

                    override fun onNext(t: T) {
                        if(t.code== ApiCode.API_SUCCESS_CODE){
                            result.onSuccess(t)
                        }else if(t.code== ApiCode.API_TOKEN_INVALID_CODE){
                            val e= LoginTokenInvalidException(t.msg)
                            result.onError(e)
                            onHandleError(e,isShowErrorToast)
                        } else{
                            val e=CodeException(t.code,t.msg)
                            result.onError(e)
                            onHandleError(e,isShowErrorToast)
                        }
                    }

                })
        }
    }
}